package com.sservice.web.controller.admin;

import com.sservice.common.Constants;
import com.sservice.common.SameUrlData;
import com.sservice.model.dao.*;
import com.sservice.model.vo.InvoicePaperBillVo;
import com.sservice.model.vo.InvoicePaperVo;
import com.sservice.model.vo.InvoiceTransferLogVo;
import com.sservice.service.service.ExportService;
import com.sservice.service.service.IOrderService;
import com.sservice.service.service.InvoicePaperService;
import com.sservice.urp.dao.IUserDao;
import com.sservice.urp.entity.User;
import com.sservice.base.entity.dto.BaseResult;
import com.sservice.base.entity.dto.ListResult;
import com.sservice.base.entity.dto.Pagination;
import com.sservice.model.entity.*;
import com.sservice.web.common.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 电子发票
 * Created by byte2 on 2017-07-02.
 */
@Controller
@RequestMapping("/admin/invoice")
public class InvoicePaperController {

    @Autowired
    private InvoicePaperMapper ipMapper;
    @Autowired
    private InvoicePaperBillMapper invoicePaperBillMapper;
    @Autowired
    private InvoicePaperService invoicePaperService;
    @Autowired
    private LadingOrderMapper loMapper;
    @Autowired
    private IOrderService orderMapper;
    @Autowired
    private IUserDao userDao;
    @Autowired
    private ILadingBillDao lbMapper;
    @Autowired
    private OtherReceivablesMapper otherReceivablesMapper;
    @Autowired
    private PurchaseOrderBillMapper purchaseOrderBillMapper;
    @Autowired
    private InvoiceTransferLogMapper itlMapper;
    @Autowired
    private ExportService exportService;

    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/open", method = RequestMethod.POST)
    public BaseResult open(InvoicePaper arv, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setCreator(String.valueOf(user.getId()));
        arv.setType("0"); // 开票
        arv.setOrderType("0"); // 发货单
        arv.setTransfer(user.getName());
        Object obj = invoicePaperService.open(arv);
        if (obj == null) {
            return new BaseResult(true, "");
        }
        return new BaseResult(false, String.valueOf(obj), 403);
    }

    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/combineOpen", method = RequestMethod.POST)
    public BaseResult combineOpen(InvoicePaperVo arv, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setCreator(String.valueOf(user.getId()));
        arv.setType("0"); // 开票
        arv.setOrderType("0"); // 发货单
        arv.setTransfer(user.getName());
        Object obj = invoicePaperService.combineOpen(arv);
        if (obj == null) {
            return new BaseResult(true, "", 200);
        }
        return new BaseResult(false, String.valueOf(obj), 403);
    }


    /**
     * 删除已开发票 order_type = 0
     * 删除已收发票 order_type = 1
     * 3期后废弃
     *
     * @param arv
     * @param request
     * @return
     */
    @ResponseBody
    @SameUrlData
    @Deprecated
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public BaseResult delete(InvoicePaper arv, HttpServletRequest request) {
        Object obj = invoicePaperService.delete(arv);
        if (obj == null) {
            return new BaseResult(true, "", 200);
        }
        return new BaseResult(false, String.valueOf(obj), 403);
    }

    /**
     * 根据发票ID删除发票
     *
     * @param arv
     * @param request
     * @return
     */
    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    public BaseResult deleteBy(InvoicePaper arv, HttpServletRequest request) {
        Object obj = invoicePaperService.deleteBy(arv);
        if (obj == null) {
            return new BaseResult(true, "", 200);
        }
        return new BaseResult(false, String.valueOf(obj), 403);
    }

    /**
     * 根据申请单号ID 和发票类型删除已开票
     *
     * @param arv
     * @return
     */
    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/delete/{orderType}/{orderId}", method = RequestMethod.POST)
    public BaseResult deleteByOrderIdAndOrderType(InvoicePaper arv) {
        Object obj = invoicePaperService.deleteBy(arv);
        if (obj == null) {
            return new BaseResult(true, "", 200);
        }
        return new BaseResult(false, String.valueOf(obj), 403);
    }

    /**
     * 收票确认
     *
     * @param arv
     * @return
     */
    @ResponseBody
    @SameUrlData
    @Transactional
    @RequestMapping(value = "/receive-confirm/${id}", method = RequestMethod.POST)
    public BaseResult receiveConfirm(InvoicePaper arv) {
        arv = ipMapper.selectByPrimaryKey(arv.getId());
        arv.setConfirm("1"); // 确认收票
        int service_res = ipMapper.updateByPrimaryKeySelective(arv);
        return new BaseResult(true, service_res);
    }

    @ResponseBody
    @RequestMapping(value = "/open/other", method = RequestMethod.POST)
    public BaseResult openOther(InvoicePaper arv, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setCreator(String.valueOf(user.getId()));
        arv.setType("0"); // 开票
        int service_res = ipMapper.insertSelective(arv);
        if (service_res > 0) {
            OtherReceivables or_ = otherReceivablesMapper.selectByPrimaryKey(Integer.valueOf(arv.getOrderId()));
            OtherReceivables lo = new OtherReceivables();
            lo.setId(or_.getId());
            if (or_.getPaperedNumber().compareTo(BigDecimal.valueOf(0.0)) == 0) {
                lo.setPaperStatus("2"); // 部分收票
            }
            lo.setPaperedNumber(BigDecimal.valueOf(arv.getNumber()).add(or_.getPaperedNumber()));
            if (lo.getPaperedNumber().compareTo(or_.getReceivables()) == 0) {
                lo.setPaperStatus("3"); // 完全收票
            }
            otherReceivablesMapper.updateByPrimaryKeySelective(lo);
        }
        return new BaseResult(true, service_res);
    }

    /***
     * 采购收票
     * @param arv
     * @param request
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/receive", method = RequestMethod.POST)
    public BaseResult receive(InvoicePaper arv, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setCreator(String.valueOf(user.getId()));
        arv.setType("1"); // 收票
        arv.setOrderType("1");
        PurchaseOrderBill lo1 = purchaseOrderBillMapper.selectByPrimaryKey(Integer.valueOf(arv.getOrderId()));
        arv.setClienteleId(String.valueOf(lo1.getClienteleId()));
        arv.setPrice(lo1.getPrice().doubleValue()); // 开票单价
        arv.setTransfer(user.getName());
        arv.setTransferId(arv.getCreator()); //
        int service_res = ipMapper.insertSelective(arv);
        if (service_res > 0) {
            PurchaseOrderBill pob = purchaseOrderBillMapper.selectByPrimaryKey(Integer.valueOf(arv.getOrderId()));
            PurchaseOrderBill or_ = new PurchaseOrderBill();
            or_.setId(pob.getId());
            if (pob.getNumberPapered().compareTo(BigDecimal.valueOf(0.0)) == 0) {
                or_.setPaperStatus("1"); // 部分收票
            }
            or_.setNumberPapered(pob.getNumberPapered().add(BigDecimal.valueOf(arv.getNumber())));
            if (pob.getNumberReceive().compareTo(or_.getNumberPapered()) == 0) {
                or_.setPaperStatus("2"); // 完全收票
            }
            purchaseOrderBillMapper.updateByPrimaryKeySelective(or_); /// 收票
        }
        return new BaseResult(true, service_res);
    }

    /**
     * 合并收票
     *
     * @param arv
     * @param request
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/combineReceive", method = RequestMethod.POST)
    public BaseResult combineReceive(InvoicePaperVo arv, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setCreator(String.valueOf(user.getId()));
        arv.setType("1"); // 收票
        arv.setOrderType("1"); // 收货单
        arv.setTransfer(user.getName());
        Object obj = invoicePaperService.combineReceive(arv);
        if (obj == null) {
            return new BaseResult(true, "", 200);
        }
        return new BaseResult(false, String.valueOf(obj), 403);
    }

    /***
     * 其他应付款款收票
     * @param arv
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/receive/other", method = RequestMethod.POST)
    public BaseResult receiveOther(InvoicePaper arv, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setCreator(String.valueOf(user.getId()));
        arv.setType("1"); // 收票

        int service_res = ipMapper.insertSelective(arv);
        if (service_res > 0) {
            OtherReceivables lo = otherReceivablesMapper.selectByPrimaryKey(Integer.valueOf(arv.getOrderId()));
            OtherReceivables or_ = new OtherReceivables();
            or_.setId(lo.getId());
            if (lo.getPaperedNumber().compareTo(BigDecimal.valueOf(0.0)) == 0) {
                or_.setPaperStatus("2"); // 部分收票
            }
            or_.setPaperedNumber(lo.getPaperedNumber().add(BigDecimal.valueOf(arv.getNumber())));
            if (or_.getPaperedNumber().compareTo(lo.getReceivables()) == 0) {
                or_.setPaperStatus("3"); // 完全收票
            }
            otherReceivablesMapper.updateByPrimaryKeySelective(or_); /// 收票
        }
        return new BaseResult(true, service_res);
    }

    /**
     * 发票
     *
     * @param arv
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/view/{orderType}", method = RequestMethod.GET)
    public ListResult viewInvoicePaper(InvoicePaperVo arv, HttpServletRequest request) {
        int total = ipMapper.countByPage(arv);
        Pagination page = new Pagination(arv.getPage(), total, arv.getSize());
        ListResult<Clientele> res = new ListResult(true, ipMapper.queryByPage(arv));
        res.setPage(page);
        return res;
    }

    @ResponseBody
    @RequestMapping(value = "/export/{orderType}", method = RequestMethod.GET)
    public OutputStream exportInvoicePaper(InvoicePaperVo arv, HttpServletRequest request, HttpServletResponse response) throws IOException {
        arv.setPage(0);
        arv.setSize(Integer.MAX_VALUE);
        List<InvoicePaperVo> list = ipMapper.queryByPage(arv);
        ServletOutputStream outputStream = response.getOutputStream();
        response.setContentType("application/binary;charset=" + "UTF-8");
        String fileName = Utils.processFileName(request, ("1".equals(arv.getOrderType()) ? "已收" : "已开") + "发票Excel");
        response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");// 组装附件名称和格式
        response.setCharacterEncoding("UTF-8");
        String hql = ("1".equals(arv.getOrderType()) ? "已收" : "已开") + "发票"; // sheet 名称
        List<Map> lm = new ArrayList<Map>();
        for (int i = 0; i < list.size(); i++) {
            Map map = new LinkedHashMap();
            InvoicePaperVo ov = list.get(i);
            map.put("发票号", ov.getNo());
            map.put("客户名称", ov.getClienteleName());
            map.put("产品", ov.getGoodsName());
            map.put("数量", ov.getNumber());
            map.put("单价", ov.getPrice());
            map.put("金额", BigDecimal.valueOf(ov.getNumber()).multiply(BigDecimal.valueOf(ov.getPrice())));
            map.put("收票人", ov.getCreator());
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
            map.put("税率", ov.getTaxRatio());
            map.put("备注", ov.getRemark());
            map.put((("1".equals(arv.getOrderType()) ? "收" : "开")) + "票日期", sdf1.format(ov.getPaperDate()));
            map.put("创建日期", sdf1.format(ov.getCreateAt()));
            lm.add(map);
        }
        return exportService.exportExcel(hql, lm, outputStream);
    }

    @ResponseBody
    @RequestMapping(value = "/view/{ladingOrderId}/{orderType}", method = RequestMethod.GET)
    public ListResult view(InvoicePaperBillVo arv, HttpServletRequest request) {
        List<String> t = invoicePaperBillMapper.selectByLadingOrderIdAndOrderType(arv);
        InvoicePaperVo ipv = new InvoicePaperVo();
        ipv.setOrderType(arv.getOrderType());//
        ipv.setInvoicePaperIds(t);
        List list = ipMapper.queryByPage(ipv);
        return new ListResult(true, list);
    }

    /***
     * 收票
     * @param arv
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/viewPurchase/{orderId}/{orderType}", method = RequestMethod.GET)
    public ListResult viewBill(InvoicePaperVo arv, HttpServletRequest request) {
//        List list = ipMapper.queryByPage(arv);
        List list = ipMapper.selectInvoiceBillBy(arv);
        return new ListResult(true, list);
    }

    @ResponseBody
    @RequestMapping(value = "/view/other/{orderId}/{orderType}", method = RequestMethod.GET)
    public ListResult viewOther(InvoicePaper arv, HttpServletRequest request) {
        List list = ipMapper.selectOtherReceivablesBy(arv);
        return new ListResult(true, list);
    }

    @ResponseBody
    @RequestMapping(value = "/transfer/{invoicePaperId}", method = RequestMethod.GET)
    public ListResult view(InvoiceTransferLogVo arv, HttpServletRequest request) {
        List list = itlMapper.selectBy(arv);
        return new ListResult(true, list);
    }

    @ResponseBody
    @RequestMapping(value = "/transfer", method = RequestMethod.POST)
    public BaseResult transfer(InvoiceTransferLog arv, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setSender(String.valueOf(user.getId()));

        int list = itlMapper.insertSelective(arv);
        InvoicePaper ip = new InvoicePaper();
        ip.setConfirm("0"); //  未收票确认
        ip.setTransferId(arv.getReceiverId()); //
        User user1 = userDao.selectByPrimaryKey(Integer.valueOf(arv.getReceiverId()));
        ip.setTransfer(user1.getName()); // 当前流转用户
        ip.setId(Integer.valueOf(arv.getInvoicePaperId()));
        ipMapper.updateByPrimaryKeySelective(ip);
        return new BaseResult(true, String.valueOf(list), 200);
    }

}
